package job.work.service.system.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import job.work.dao.system.dao.DecMenuDao;
import job.work.dao.system.dao.DecRoleMenuDao;
import job.work.domain.response.*;
import job.work.domain.system.SysBool;
import job.work.domain.system.entity.pojo.DecMenu;
import job.work.domain.system.entity.pojo.DecRole;
import job.work.domain.system.entity.pojo.model.SystemUser;
import job.work.domain.system.request.MenuPageRequest;
import job.work.domain.system.request.SysPageListReq;
import job.work.framework.CustomException;
import job.work.mapper.system.RoleMapper;
import job.work.mapper.system.SystemMapper;
import job.work.service.system.service.SystemService;
import job.work.utils.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

@Service
@Slf4j
public class SystemServiceImpl implements SystemService {

    @Resource
    TokenUtil tokenUtil;

    @Resource
    SystemMapper systemMapper;

    @Resource
    RoleMapper roleMapper;

    @Autowired
    SystemService systemService;

    @Autowired
    DecMenuDao decMenuDao;

    @Autowired
    DecRoleMenuDao decRoleMenuDao;

    @Autowired
    DecMenuServiceImpl decMenuService;



    /**
     * 根据用户名查询用户
     *
     * @param username 用户名
     * @return 信息
     */
    @Override
    public SystemUser findSystemUserName(String username) {
        return systemMapper.findByUsername(username);
    }

    /**
     * 根据手机号查询用户信息
     *
     * @param mobile 手机号
     * @return
     */
    @Override
    public SystemUser findSystemMobile(String mobile) {
        return systemMapper.findByMobile(mobile);
    }


    /**
     * 根据用户角色id查询用户角色
     *
     * @param id 角色Id
     * @return 用户角色
     */
    @Override
    public DecRole findRole(Long id) {
        Optional<DecRole> byId = roleMapper.findByRoleId(id);
        return byId.orElse(null);
    }


    /**
     * 修改密码
     *
     * @param safetyRequestResponse 密码接收类
     * @return ResponseResult
     */
    @Override
    @Transactional
    public ResponseResult saveUserPassword(SafetyResponse safetyRequestResponse) {
        SystemUser token = tokenUtil.token();
        SystemUser byMobile = systemMapper.findById(token.getId());

        //判断现密码长度是否小于6位
        if (safetyRequestResponse.getOriginal().length() < 6) {
            return new ResponseResult<>(AuthCode.PASSWORD_ORIGINAL_LENGTH);
        }

        //判断两次密码是否一致
        if (!safetyRequestResponse.getOriginal().equals(safetyRequestResponse.getOriginalPassword())) {
            return new ResponseResult<>(AuthCode.PASSWORD_ILLEGAL);
        }

        //判断原密码和数据库密码是否一致
        boolean matches = this.password(safetyRequestResponse.getPresentPassword(), byMobile.getPassword());
        if (!matches) {
            return new ResponseResult<>(AuthCode.PASSWORD_ORIGINAL_ILLEGAL);
        }

        //新密码
        String password = this.password(safetyRequestResponse.getOriginal());
        byMobile.setPassword(password);

        systemMapper.updatePassword(token.getId(), password);

        return ResponseResult.SUCCESS();
    }


    /**
     * 禁用账户或者解禁账户
     *
     * @param sysId  用户ID
     * @param status 状态
     * @return 是否成功
     */
    @Override
    @Transactional
    public ResponseResult prohibitUser(Long sysId, Integer status) {
        if (status == 0 || status == 1) {
            SystemUser byMobile = systemMapper.findById(sysId);
            if (byMobile != null) {
                byMobile.setStatus(status);
                systemMapper.updateStatus(sysId, status);

                return ResponseResult.SUCCESS();
            }
        }
        return ResponseResult.FAIL();

    }


    /**
     * 重置当前账号密码
     *
     * @param id  用户ID
     * @param pwd 账号密码
     * @return ResponseResult
     */
    @Override
    @Transactional
    public ResponseResult resetPassword(Long id, String pwd) {

        SystemUser byMobile = systemMapper.findById(id);
        if (byMobile != null) {
            String password = this.password(pwd);
            systemMapper.updatePassword(id, password);
            return ResponseResult.SUCCESS();
        }
        return ResponseResult.FAIL();
    }


    /**
     * 添加
     *
     * @param system 信息表
     * @return ResponseResult
     */
    @Override
    @Transactional
    public ResponseResult saveSystem(SystemUser system) {
        //管理员角色ID
        Long roleId = Objects.equals(system.getRoleId(),null) ? 2L:system.getRoleId();

        Optional<DecRole> byRoleId = roleMapper.findByRoleId(roleId);

        if(!byRoleId.isPresent()){
            return new ResponseResult(CommonCode.FAIL,"未有此权限!");
        }
        system.setRoleId(roleId);

        system.setStatus(0);
        //判断账户是否重复
        if (this.isName(system.getId(), system.getUsername())) {
            return new ResponseResult(CommonCode.FAIL, "当前账户名称重复!");
        }
        if (this.isPhone(system.getId(), system.getPhone())) {
            return new ResponseResult(CommonCode.FAIL, "当前手机号重复!");
        }
        SystemUser save = this.save(system);
        return ResponseResult.SUCCESS();
    }

    /**
     * 根据ID和用户名判断名称是否重复
     *
     * @param id       用户ID
     * @param username 用户名
     * @return true/false
     */
    @Override
    public boolean isName(Long id, String username) {
        SystemUser byUsername = systemMapper.findByUsername(username);
        return this.isRepaet(id, byUsername);
    }

    /**
     * 根据ID和手机号判断名称是否重复
     *
     * @param id    用户ID
     * @param phone 手机号
     * @return true/false
     */
    @Override
    public boolean isPhone(Long id, String phone) {
        SystemUser byUsername = systemMapper.findByMobile(phone);
        return this.isRepaet(id, byUsername);
    }


    public boolean isRepaet(Long id, SystemUser byUsername) {
        if (id == null) {
            return byUsername != null;
        } else {
            if (byUsername == null) {
                return false;
            }
            return !id.equals(byUsername.getId());
        }
    }

    /**
     * 保存或者修改用户信息
     *
     * @param system 用户信息
     * @return 返回数据
     */
    @Override
    public SystemUser save(SystemUser system) {

        if (system.getId() == null) {
            //加密密码
            String password;
            if (!StringUtils.isEmpty(system.getPassword())) {
                password = this.password(system.getPassword());
            } else {
                password = this.password("123456");
            }
            system.setPassword(password);
            system.setType(1);
            system.setStatus(0);
            //创建时间
            system.setCreateTime(new Date());
        }
        system.setLastLoginTime(new Date());
        if (system.getId() == null) {
            system.setWallet(new BigDecimal("0.00"));
            systemMapper.insert(system);
        } else {
            SystemUser byId = systemMapper.findById(system.getId());
            system.setPassword(byId.getPassword());
            system.setCreateTime(system.getCreateTime());
            systemMapper.updateByPrimaryKeySelective(system);
        }
        return system;
    }

    /**
     * 加密
     *
     * @param password 输入的密码
     * @return 加密后的密码
     */
    @Override
    public String password(String password) {
        return new BCryptPasswordEncoder().encode(password);
    }

    /**
     * 解密
     *
     * @param password1 未加密的密码(用户输入的)
     * @param password2 加密后的密码(数据库)
     * @return 返回是否一致
     */
    @Override
    public Boolean password(String password1, String password2) {
        return new BCryptPasswordEncoder().matches(password1, password2);
    }

    /**
     * 根据id删除管理员
     *
     * @param id 用户ID
     * @return 操作结果
     */

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult deleteById(Long id) {

        SystemUser byId = systemMapper.findById(id);
        if (byId == null) {
            return new ResponseResult(CommonCode.PARAM_ERROR);
        }
        Optional<DecRole> byRoleId = roleMapper.findByRoleId(byId.getRoleId());
        if (byRoleId.isPresent()) {
            systemMapper.delete(byId);
            return ResponseResult.SUCCESS();
        }

        return ResponseResult.FAIL();
    }

    /**
     * 分页查询管理员数据
     *
     * @param menuPageRequest 请求参数
     * @return 操作数据
     */
    @Override
    public ResponseResult findPageSystem(MenuPageRequest menuPageRequest) {
        SysPageListReq sysPageListReq = new SysPageListReq();
        sysPageListReq.setName(menuPageRequest.getName());
        sysPageListReq.setPageNumber(menuPageRequest.getPageNumber());
        sysPageListReq.setPageSize(menuPageRequest.getPageSize());
        //sysPageListReq.setRoleId(2L);
        Page<SystemUser> systems = this.findPageLike(sysPageListReq);
        return new ResponseResult<>(CommonCode.SUCCESS, new PageResult<>(systems.getTotal(), systems.getResult()));
    }

    /**
    * 封装角色id
    * */
    private Set<Long> makeIdSet(List<DecRole> decRoles){
        Set<Long> num = new HashSet<>(decRoles.size());
        decRoles.forEach(obj -> num.add(obj.getId()));

        return num;
    }
    /**
     * 根据 参数分页查询数据
     *
     * @return 分页数据
     */
    @Override
    public Page<SystemUser> findPageLike(SysPageListReq sysPageListReq) {
        System.out.println();
        System.out.println("輸出測試下menuPageRequest---->:"+sysPageListReq);
        System.out.println();
        SystemUser token = tokenUtil.token();
        // 用户名 手机号 或者 昵称
        String name = sysPageListReq.getName();
        //当前页
        int pageNumber = sysPageListReq.getPageNumber();
        //每页显示条数
        int pageSize = sysPageListReq.getPageSize();
        //角色ID
        Set<Long> roleId = new HashSet<>();
        //查询可修改活跃角色
        //状态
        Integer status = sysPageListReq.getStatus();
        //用户Id
        Set<Long> sysId = sysPageListReq.getSysId();

        Example example = new Example(SystemUser.class);
        Example.Criteria criteria = example.createCriteria();
        if (!StringUtils.isEmpty(name)) {
            criteria.orLike("username", "%" + name + "%");
            criteria.orLike("phone", "%" + name + "%");
            criteria.orLike("wxNickName", "%" + name + "%");
            criteria.orLike("qqNickName", "%" + name + "%");
        }
        Example.Criteria criterias = example.createCriteria();
        if (sysId != null && sysId.size() > 0) {
            criterias.andIn("id", sysId);
        } else if (sysId == null) {
            criterias.andNotEqualTo("id", token.getId());
        }
        if (status != null) {
            criterias.andEqualTo("status", status);
        }

        if(roleId.size() != 0){
            criterias.andIn("roleId",roleId);
        }
        //测试功能!查询所有角色包括用户:基表 上线请取消!
        //criterias.andEqualTo("roleId", roleId);
        example.and(criterias);
        PageHelper.startPage(pageNumber, pageSize);
        return (Page<SystemUser>) systemMapper.selectByExample(example);
    }


    /**
     * 根据用户ID保存用户角色
     *
     * @param sysId  用户Id
     * @param roleId 角色ID
     */
    @Override
    public void saveSysRole(Long sysId, Long roleId) {
        systemMapper.updateRoleId(sysId, roleId);
    }




    /**
     * 判断是否需要修改登录密码
     *
     * @return ResponseResult
     */
    @Override
    public ResponseResult isSysPassword() {
        SystemUser byMobile = tokenUtil.token();
        log.info("输出下byM--->{}", byMobile);

        SysBool sysBool = new SysBool();
        sysBool.setSystemUser(byMobile);

        if (byMobile != null) {
            if (byMobile.getType() == 1) {
                sysBool.setFlag(true);
                log.info("输出测试下sysBool---->{}", sysBool.toString());
                return new ResponseResult<>(CommonCode.SUCCESS, sysBool);
            }
        }

        sysBool.setFlag(false);
        log.info("输出测试下sysBool->{}", sysBool.toString());
        return new ResponseResult<>(CommonCode.SUCCESS, sysBool);
    }




    /**
     * 获取用户信息
     *
     * @return 操作结果
     */
    @Override
    public ResponseResult pickUpInformation() {
        SystemUser token = tokenUtil.token();
        Set<String> set = new HashSet<>();
        //查询所属角色权限中间表
//        List<DecRoleMenu> byRoleId = decRoleMenuDao.findByRoleId(token.getRoleId());
//        for(DecRoleMenu rm:byRoleId){
//            //查询具体权限
//            Optional<DecMenu> byId = decMenuDao.findById(rm.getMenuId());
//            set.add(byId.get().getName());
//        }
        List<DecMenu> decMenus = decMenuService.rolesList(token.getRoleId());
        for (DecMenu ds : decMenus) {
            set.add(ds.getName());
        }

        token.setUserPermission(set);

        return new ResponseResult<>(CommonCode.SUCCESS, token);
    }

    /**
     * 修改钱包
     *
     * @param id     用户Id
     * @param wallet 钱包金额
     */
    @Override
    public void saveWallet(Long id, BigDecimal wallet) {
        systemMapper.updateWallet(id, wallet);
    }





}